﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;

namespace MMOG
{
    public class Point3d
    {
        public float x, y, z;

        public Point3d(float x, float y, float z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }

    public class VertexInfo
    {
        public int v, vt, vn;

        public VertexInfo(int v, int vt, int vn)
        {
            this.v = v;
            this.vt = vt;
            this.vn = vn;
        }
    }

    public class Face
    {
        public VertexInfo[] data;
        public Face(VertexInfo[] data)
        {
            this.data = data;
        }
    }

    public class Object3d
    {
        public Collection<Point3d> vertice;
        public Collection<Face> face;
        public Collection<Point3d> textureCoord;
        public Collection<Point3d> normal;
        public String material;

        public Object3d()
        {
        }

        public Object3d(String filename)
        {
            loadObj(filename);
        }

        public bool loadObj(String filename)
        {
            try
            {
                StreamReader reader = new StreamReader(filename);
                String line;

                vertice = new Collection<Point3d>();
                face = new Collection<Face>();
                textureCoord = new Collection<Point3d>();
                normal = new Collection<Point3d>();
                material = null;

                //For each line of the obj file
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Length == 0) continue;
                    String[] split = new String[1];
                    split[0] = " ";
                    String[] strArr = line.Split(split, StringSplitOptions.RemoveEmptyEntries);

                    //Ignore comment line started by '#'
                    if (strArr[0].Equals("#")) continue;

                    //Material library
                    if (strArr[0].Equals("mtllib")) continue;

                    //Group
                    if (strArr[0].Equals("g")) continue;

                    //Geometric Vertices
                    if (strArr[0].Equals("v"))
                    {
                        float x = float.Parse(strArr[1]);
                        float y = float.Parse(strArr[2]);
                        float z = float.Parse(strArr[3]);
                        vertice.Add(new Point3d(x, y, z));
                    }

                    //Texture Vertices
                    if (strArr[0].Equals("vt"))
                    {
                        float x = float.Parse(strArr[1]);
                        float y = float.Parse(strArr[2]);
                        float z = float.Parse(strArr[3]);
                        textureCoord.Add(new Point3d(x, y, z));
                    }

                    //Vertex Normals
                    if (strArr[0].Equals("vn"))
                    {
                        float x = float.Parse(strArr[1]);
                        float y = float.Parse(strArr[2]);
                        float z = float.Parse(strArr[3]);
                        normal.Add(new Point3d(x, y, z));
                    }

                    //Use material
                    if (strArr[0].Equals("usemtl"))
                    {
                        material = strArr[1];
                    }

                    //Smoothing groups
                    if (strArr[0].Equals("s")) continue;

                    //Faces
                    if (strArr[0].Equals("f"))
                    {
                        VertexInfo[] v = new VertexInfo[3]; ;
                        for (int i = 0; i < 3; i++)
                        {
                            String[] s = strArr[i + 1].Split('/');
                            int vv = int.Parse(s[0]);
                            int vt = int.Parse(s[1]);
                            int vn = int.Parse(s[2]);
                            v[i] = new VertexInfo(vv, vt, vn);
                        }
                        face.Add(new Face(v));
                    }
                }
                reader.Close();
            }
            catch (IOException)
            {
                return false;
            }
            return true;
        }
    }
}
